package com.lute.model;

import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import org.springframework.security.oauth2.common.json.JSONArray;
import org.springframework.security.oauth2.common.json.JSONException;
import org.springframework.security.oauth2.common.json.JSONObject;

import com.lute.utils.DAOFactory;
import com.lute.utils.LuteDAO;
import com.lute.utils.ServerErrorResponse;

@Entity
@DiscriminatorValue("Employee")
public class Employee extends User implements Serializable  {

	private static final long serialVersionUID = 1L;

	private EmployeeProfile employeeProfil;
	private List<EmployeeAccountingPeriod> employeeAccountingPeriods =
			new ArrayList<EmployeeAccountingPeriod>();

	
	public Employee() {} 
	public Employee(String firstName, String lastName, String login, String email, Role role) {
		super(firstName,lastName,login,email,role);
	}
	
	@OneToOne(cascade=CascadeType.ALL, mappedBy="employee")
	public EmployeeProfile getEmployeeProfil() {
		return employeeProfil;
	}
	public void setEmployeeProfil(EmployeeProfile employeeProfil) {
		this.employeeProfil = employeeProfil;
	}
	
	@OneToMany(targetEntity=EmployeeAccountingPeriod.class, mappedBy="employee",
			cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	public List<EmployeeAccountingPeriod> getEmployeeAccountingPeriods() {
		return employeeAccountingPeriods;
	}
	public void setEmployeeAccountingPeriods(
			List<EmployeeAccountingPeriod> employeeAccountingPeriods) {
		this.employeeAccountingPeriods = employeeAccountingPeriods;
	}
	
	public static EmployeeAccountingPeriod getAccountingPeriod(String propertyName, int propertyValue, String type, String from) {
		Employee employee = (Employee)DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseByIdWithAccPeriod(propertyName, propertyValue);
		List<EmployeeAccountingPeriod> employeeAccountingPeriods = employee.getEmployeeAccountingPeriods();
		for(EmployeeAccountingPeriod empAccountingPeriod : employeeAccountingPeriods) {
			if( !(from.equals("")) ) {
				SimpleDateFormat dateFromater = new SimpleDateFormat("yyyy-MM-dd");
				if(dateFromater.format(empAccountingPeriod.getClientAccountingPeriod().getDate_from().getTime()).equals(from)) {
					EmployeeAccountingPeriod emplAccPeriod = EmployeeAccountingPeriod.getEmployeeAccountingPeriodByIdDB(
							"id_employee_accounting_period",empAccountingPeriod.getId_employee_accounting_period());
					return emplAccPeriod;
				}
			} else {
				if(empAccountingPeriod.getClientAccountingPeriod().getClientAccountingPeriodState().equals(type)) {
					EmployeeAccountingPeriod emplAccPeriod = EmployeeAccountingPeriod.getEmployeeAccountingPeriodByIdDB(
							"id_employee_accounting_period",empAccountingPeriod.getId_employee_accounting_period());
					return emplAccPeriod;
				}
			}
		}
		return null;
	}
	
	
	public static Employee getEmployeeFromDB(String propertyName, int propertyValue) {
		return DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseById(propertyName, propertyValue);
	}

	public static Employee getEmployeeFromDBWithProfile(String propertyName, int propertyValue) {
		return DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseByIdWithProfile(propertyName, propertyValue);
	}
	
	public static Employee getEmployeeWithEmployeeAccPeriodsFromDB(String propertyName, int propertyValue) {
		return DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseByIdWithAccPeriod(propertyName, propertyValue);
	}
	
	public static List<Employee> getEmployeesFromDB() {
		return DAOFactory.getInstance().getLuteInterface().getEmployeesFromDataBase();
	}
	
	public static List<Employee> getEmployeesByAccLockedFromDB(String propertyName, String propertyValue) {
		return DAOFactory.getInstance().getLuteInterface().getEmployeesByAccLockedFromDataBase(propertyName, propertyValue);
	}
	
	public static synchronized int addNewEmployeeToDB(Employee employee) {
		return DAOFactory.getInstance().getLuteInterface().addNewEmployeeAndGetIdFromDataBase(employee);
	}
	
	public static String getEmployeeAccountingPeriodStateBasedOnEmployeeIdAndFrom(String propertyName, int propertyValue, String from){
		String returnValue = null;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date fromGregorianCalendar = null;
		GregorianCalendar date = null;
		
		Employee employee = (Employee)DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseByIdWithAccPeriodClientAccPeriodEmployeeEntries(propertyName, propertyValue);
		List<EmployeeAccountingPeriod> employeeAccountingPeriods = employee.getEmployeeAccountingPeriods();

		EmployeeAccountingPeriod requestedEmployeeAccountingPeriod = null;
		for (EmployeeAccountingPeriod employeeAccountingPeriod : employeeAccountingPeriods) {
			try {
				fromGregorianCalendar = simpleDateFormat.parse(from);
				date = new GregorianCalendar();
				date.setTime(fromGregorianCalendar);
				if (employeeAccountingPeriod.getClientAccountingPeriod().getDate_from().equals(date)){
					requestedEmployeeAccountingPeriod = employeeAccountingPeriod;
				}
			} catch (ParseException e) {
				e.printStackTrace();
				return null;
			}
		}
		
		if (requestedEmployeeAccountingPeriod == null){
			// System.out.println("Rejection reason - wrong initial date");
			return null;
		}

		return requestedEmployeeAccountingPeriod.getEmployeeAccountingPeriodState().toString();
	}

	
	public static boolean updateAccountingPeriodCalendarEntries(String propertyName, int propertyValue, String from, String calendarEntriesToUpdate){
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date fromGregorianCalendar = null;
		GregorianCalendar date = null;
		
		Employee employee = (Employee)DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseByIdWithAccPeriodClientAccPeriodEmployeeEntries(propertyName, propertyValue);
		List<EmployeeAccountingPeriod> employeeAccountingPeriods = employee.getEmployeeAccountingPeriods();
		for (EmployeeAccountingPeriod employeeAccountingPeriod : employeeAccountingPeriods) {
			System.out.println("GOT FROM DB: EmployeeAccountingPeriodId = " + employeeAccountingPeriod.getId_employee_accounting_period());
		}

		// seek by parameter FROM within ClientAccountingPeriod
		EmployeeAccountingPeriod requestedEmployeeAccountingPeriod = null;
		for (EmployeeAccountingPeriod employeeAccountingPeriod : employeeAccountingPeriods) {
			try {
				fromGregorianCalendar = simpleDateFormat.parse(from);
				date = new GregorianCalendar();
				date.setTime(fromGregorianCalendar);
				if (employeeAccountingPeriod.getClientAccountingPeriod().getDate_from().equals(date)){
					requestedEmployeeAccountingPeriod = employeeAccountingPeriod;
					System.out.println("GET FROM DB: EmployeeAccountingPeriodId = " + employeeAccountingPeriod.getId_employee_accounting_period());
					System.out.println("EmplAccPeriod userID = " + requestedEmployeeAccountingPeriod.getEmployee().getId_user());
					// System.out.println("dates are the same");
				}
			} catch (ParseException e) {
				e.printStackTrace();
				return false;
			}
		}
		
		// if no accounting period starts with date FROM - finish
		if (requestedEmployeeAccountingPeriod == null){
			// System.out.println("Rejection reason - wrong initial date");
			return false;
		}
		
		// delete all entries in NotepadEntry table for given accounting period
		List<EmployeeEntry> employeeEntriesToDelete = requestedEmployeeAccountingPeriod.getEmployeeEntries();
		DAOFactory.getInstance().getLuteInterface().deleteEmployeeEntriesFromEmployeeAccountingPeriod(employeeEntriesToDelete);
		// System.out.println("After deletion all NotepadEntries from Employee Acc Period");
		
		// update DB with new notepad entries that are taken from UI
		boolean returnValue = false;
		List<EmployeeEntry> list = new ArrayList<EmployeeEntry>();
		
		try {
			JSONArray calendarEntries = new JSONArray(calendarEntriesToUpdate);
			
			for(int i = 0; i < calendarEntries.length(); i++){
				// System.out.println("i = " + i);
				JSONObject calendarEntry = calendarEntries.getJSONObject(i);
				EmployeeEntry ee = new EmployeeEntry();
				try {
					fromGregorianCalendar = simpleDateFormat.parse(calendarEntry.getString("date"));
					date = new GregorianCalendar();
					date.setTime(fromGregorianCalendar);
					
					String companyCategory = calendarEntry.getString("companyCategory");
					CompanyCategory cc = DAOFactory.getInstance().getLuteInterface().getCompanyCategoryFromDataBase("name", companyCategory);
					int hours = Integer.parseInt(calendarEntry.getString("hours"));
					int creativeHours = Integer.parseInt(calendarEntry.getString("creativeHours"));
					
					ee.setDate(date);
					ee.setHours(hours);
					ee.setCreativeHours(creativeHours);
					ee.setCompanyCategory(cc);
					list.add(ee);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}
			
			requestedEmployeeAccountingPeriod.setEmployeeEntries(list);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(requestedEmployeeAccountingPeriod);
			System.out.println("EmployeeEntry inserted: " + calendarEntries.toString());
			returnValue = true;
			
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return returnValue;
	}
	
	public static List<EmployeeEntry> getEmployeeEntriesListFromJSON(String employeeEntriesJSON) throws JSONException{
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date fromGregorianCalendar = null;
		GregorianCalendar date = null;
		List<EmployeeEntry> list = new ArrayList<EmployeeEntry>();

		try {
			JSONArray calendarEntries = new JSONArray(employeeEntriesJSON);
			
			for(int i = 0; i < calendarEntries.length(); i++){
				// System.out.println("i = " + i);
				JSONObject calendarEntry = calendarEntries.getJSONObject(i);
				EmployeeEntry ee = new EmployeeEntry();

					fromGregorianCalendar = simpleDateFormat.parse(calendarEntry.getString("date"));
					date = new GregorianCalendar();
					date.setTime(fromGregorianCalendar);
					
					String companyCategory = calendarEntry.getString("companyCategory");
					CompanyCategory cc = DAOFactory.getInstance().getLuteInterface().getCompanyCategoryFromDataBase("name", companyCategory);
					int hours = Integer.parseInt(calendarEntry.getString("hours"));
					int creativeHours = Integer.parseInt(calendarEntry.getString("creativeHours"));
					
					ee.setDate(date);
					ee.setHours(hours);
					ee.setCreativeHours(creativeHours);
					ee.setCompanyCategory(cc);
					list.add(ee);
			}
		} catch (ParseException e) {
			System.out.println("JSON Parsing Exception");
			return list;
		}
		
		return list;
	}
	
	public static boolean updateEmail(String propertyName, int propertyValue,String userRole, String email){
		// update email as field in Employee
		Employee employee = (Employee)DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseById(propertyName, propertyValue);
		employee.setEmail(email);
		DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employee);
		
		// update email as field in EmployeeProfile
		EmployeeProfile employeeProfile = (EmployeeProfile)DAOFactory.getInstance().getLuteInterface().getEmployeeProfileByEmployeeIdFromDataBase(userRole, propertyValue);
		employeeProfile.setEmail(email);
		DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
		return true;
	}
	
	//																	"id_user", 			employeeId, 		"employee"		"startWorking"  "2013-06-11"
	public static boolean updateEmployeeProfileGregorianCalendarDate(String propertyName, int propertyValue, String userRole, String typeOfDate, String dateToChange){
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date dateDate = null;
		GregorianCalendar date = null;
		boolean returnValue = false;
		
		try {
			dateDate = simpleDateFormat.parse(dateToChange);
			date = new GregorianCalendar();
			date.setTime(dateDate);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		
		EmployeeProfile employeeProfile = (EmployeeProfile)DAOFactory.getInstance().getLuteInterface().getEmployeeProfileByEmployeeIdFromDataBase(userRole, propertyValue);
		
		if (typeOfDate.equals("startWorking")){
			employeeProfile.setStartWorking(date);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
			returnValue = true;
		} else if (typeOfDate.equals("workLifeLine")){
			employeeProfile.setWorkLifeLine(date);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
			returnValue = true;
		} else if (typeOfDate.equals("billingStartDate")){
			employeeProfile.setBillingStartDate(date);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
			returnValue = true;
		} else {
			returnValue = false;
		}
		
		return returnValue;
	}
	
	public static boolean updateEmployeeProfileClient(String propertyName, int propertyValue, String userRole, String clientName) {
		boolean returnValue = false;
		Client client = (Client)DAOFactory.getInstance().getLuteInterface().getClientFromDataBase("name", clientName);		
		EmployeeProfile employeeProfile = (EmployeeProfile)DAOFactory.getInstance().getLuteInterface().getEmployeeProfileByEmployeeIdFromDataBase(userRole, propertyValue);
		
		if (client.getName().equals(employeeProfile.getClient().getName())){
			employeeProfile.setClient(client);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
			returnValue = true;
		}

		return returnValue;
	}
	
	public static boolean updateEmployeeProfileBusinessUnit(String propertyName, int propertyValue, String userRole, String businessUnitName) {
		boolean returnValue = false;
		BusinessUnit businessUnit = (BusinessUnit)DAOFactory.getInstance().getLuteInterface().getBusinessUnitFromDataBase("name", businessUnitName);
		EmployeeProfile employeeProfile = (EmployeeProfile)DAOFactory.getInstance().getLuteInterface().getEmployeeProfileByEmployeeIdFromDataBase(userRole, propertyValue);
		
		if (businessUnit.getName().equals(employeeProfile.getBusinessUnit().getName())){
			employeeProfile.setBusinessUnit(businessUnit);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
			returnValue = true;
		}
		
		return returnValue;
	}

	public static boolean updateEmployeeProfileEmploymentStatus(String propertyName, int propertyValue, String userRole, String employmentStatus){
		boolean returnValue = false;
		
		EmployeeProfile employeeProfile = (EmployeeProfile)DAOFactory.getInstance().getLuteInterface().getEmployeeProfileByEmployeeIdFromDataBase(userRole, propertyValue);		
		employeeProfile.setEmploymentStatus(employmentStatus);
		DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
		returnValue = true;
		
		return returnValue;
	}

	public static boolean updateEmployeeProfilePosition(String propertyName, int propertyValue, String userRole, String positionName) {
		boolean returnValue = false;
		Position position = (Position)DAOFactory.getInstance().getLuteInterface().getPositionFromDataBase("name", positionName);
		EmployeeProfile employeeProfile = (EmployeeProfile)DAOFactory.getInstance().getLuteInterface().getEmployeeProfileByEmployeeIdFromDataBase(userRole, propertyValue);
		
		if (position.getName().equals(employeeProfile.getBusinessUnit().getName())){
			employeeProfile.setPositions(position);
			DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeProfile);
			returnValue = true;
		}
		
		return returnValue;
	}
	
	public static List<EmployeeProfile> getEmployeeProfiles(List<Employee> employees) {
		List<EmployeeProfile> profiles = new ArrayList<EmployeeProfile>();
		for(Employee employee: employees) {
			profiles.add(employee.getEmployeeProfil());
		}
		return profiles;
	}
	public static JSONObject verifyEmployeeEntriesAndChangeEmployeeAccountingPeriodState(String propertyName, int propertyValue, String from, String calendarEntriesToUpdate) throws JSONException {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date fromGregorianCalendar = null;
		GregorianCalendar date = null;
		JSONObject jsonRes = new JSONObject();
		jsonRes.put("result", "");

		Employee employee = (Employee)DAOFactory.getInstance().getLuteInterface().getEmployeeFromDataBaseByIdWithAccPeriodClientAccPeriodEmployeeEntries(propertyName, propertyValue);
		List<EmployeeAccountingPeriod> employeeAccountingPeriods = employee.getEmployeeAccountingPeriods();
		
//		System.out.println("Before FOR EACH loop");
		// seek by parameter FROM within ClientAccountingPeriod
		for (EmployeeAccountingPeriod employeeAccountingPeriod : employeeAccountingPeriods) {
			try {
				fromGregorianCalendar = simpleDateFormat.parse(from);
				date = new GregorianCalendar();
				date.setTime(fromGregorianCalendar);
//				System.out.println("Before first IF ELSE statement");
//				System.out.println(employeeAccountingPeriod.getClientAccountingPeriod().getDate_from());
//				System.out.println(date);
				if (employeeAccountingPeriod.getClientAccountingPeriod().getDate_from().equals(date)){
					if (employeeAccountingPeriod.getClientAccountingPeriod().getClientAccountingPeriodState().equals(ClientAccountingPeriodState.CLOSE.toString())){
//						System.out.println("Reason: ClientAccountingPeriodState = CLOSE");
						jsonRes.put("result", ServerErrorResponse.ACCOUNTING_PERIOD_ALREADY_CLOSED.toString());
						return jsonRes;
					} else {
//						if (employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.SENT_TO_CLIENT_ADMIN.toString())){
//							System.out.println("Reason: EmployeeAccountingPeriodState already SENT_TO_CA");
//							jsonRes.put("result", ServerErrorResponse.ACCOUNTING_PERIOD_ALREADY_SENT_TO_CA.toString());
//							return jsonRes;
//						} else 
						if (employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.INITIAL.toString()) ||
							employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.SENT_TO_APPROVER.toString()) ||
							employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.REJECTED_BY_APPROVER.toString()) ||
							employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.CHECKED_BY_APPROVER.toString()) ||
							employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.CHECKED_BY_CLIENT_ADMIN.toString()) ||
							employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.REJECTED_BY_CLIENT_ADMIN.toString()) ||
							employeeAccountingPeriod.getEmployeeAccountingPeriodState().equals(EmployeeAccountingPeriodState.SENT_TO_CLIENT_ADMIN.toString())){
							
							List<EmployeeEntry> list = getEmployeeEntriesListFromJSON(calendarEntriesToUpdate);
							jsonRes = doAccountingPeriodVerification(employeeAccountingPeriod, list, jsonRes);
							if(!(jsonRes.get("result").equals(""))) {
								System.out.println(jsonRes.toString());
								return jsonRes;
							}

							employeeAccountingPeriod.setEmployeeAccountingPeriodState(EmployeeAccountingPeriodState.SENT_TO_CLIENT_ADMIN.toString());
							DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(employeeAccountingPeriod);
							jsonRes.put("result", "OK");
		    				jsonRes.put("newEmployeeAccountingPeriodState", employeeAccountingPeriod.getEmployeeAccountingPeriodState());
		    				
//							System.out.println("NORMAL CHANGE");
						} else {
							jsonRes.put("result", ServerErrorResponse.INVALID_EMPLOYEE_ACCOUNTING_PERIOD_STATE_CHANGE.toString());
						}
					}
				}
			} catch (ParseException e) {
				e.printStackTrace();
				jsonRes.put("result", ServerErrorResponse.MALFORMED_REQUEST.toString());
				return jsonRes;
			}
		}

		return jsonRes;
	}
	
	public static JSONObject doAccountingPeriodVerification(EmployeeAccountingPeriod period, List<EmployeeEntry> entriesToVerify, JSONObject jsonRes) throws JSONException {
		List<EmployeeEntry> employeeEntries = entriesToVerify;
		Integer creativityPercentage = null;
		
		if(period.getEmployee() == null) {
			if(!(period.getApprover().getApproverProfile().getPositions().getName().equals(PositionName.SUPPORT.toString()))) {
				creativityPercentage = period.getApprover().getApproverProfile().getPositions().getCreativity_percentage();
			}
		} else {
			if(!(period.getEmployee().getEmployeeProfil().getPositions().getName().equals(PositionName.SUPPORT.toString()))) {
				creativityPercentage = period.getEmployee().getEmployeeProfil().getPositions().getCreativity_percentage();
			}
		}
		int workHours = 0;
		int creativeHoursSum = 0;
		
		if(employeeEntries.size() == 0) {
			jsonRes.put("result",ServerErrorResponse.CALENDAR_IS_EMPTY.toString());
			return jsonRes;
		}

		for(EmployeeEntry entry: employeeEntries) {
			if(entry.getCompanyCategory() == null) {
				jsonRes.put("result",ServerErrorResponse.CALENDAR_CONTAINS_EMPTY_DAYS.toString());
				return jsonRes;
			}
			if(entry.getHours() < 8.0) {
				jsonRes.put("result",ServerErrorResponse.CALENDAR_CONTAINS_DAYS_BELOW_8H.toString());
				return jsonRes;
			}
			
			if(entry.getCompanyCategory().getName().equals(CompanyHoursCategory.WORK_CLIENT.toString()) ||
			   entry.getCompanyCategory().getName().equals(CompanyHoursCategory.WORK_COMPANY.toString()))
			{
				workHours += entry.getHours();
			}
			creativeHoursSum += entry.getCreativeHours();
		}
		if(creativityPercentage != null) {
			float creativeHoursBase = ((float)(workHours * creativityPercentage)) / 100;
			int creativeHours = 0;
			
			if( ((int)(creativeHoursBase + 0.5)) > (int)creativeHoursBase ) {
				creativeHours = ((int)creativeHoursBase) + 1;
			} else {
				creativeHours = (int)creativeHoursBase;
			}
			
			
			if( (creativeHoursSum > creativeHours)) {
				jsonRes.put("result",ServerErrorResponse.TOO_MANY_CREATIVE_HOURS.toString());
				return jsonRes;
			}
			if((creativeHoursSum < creativeHours )) {
				jsonRes.put("result",ServerErrorResponse.NOT_ENOUGH_CREATIVE_HOURS.toString());
				return jsonRes;
			}
		}
		
		return jsonRes;
	}

}



